<template>
	<view class="trajectory-container">
		<map id="trajectoryMap" v-if="latitude && longitude" :latitude="latitude" :longitude="longitude" :scale="14"
			class="map-area" :markers="markers" :polyline="polyline" show-location></map>
		<view class="info-card" :style="{ transform: `translate(${cardPosition.x}px, ${cardPosition.y}px)` }"
			@touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd">
			<view class="drag-handle">
				<view class="handle-line"></view>
			</view>
			<text class="label">当前位置</text>
			<view class="coords flex">
				<text>经度：</text>
				<text class="value">{{ longitude ? longitude : '获取中...' }}</text>
			</view>
			<view class="coords flex">
				<text>纬度：</text>
				<text class="value">{{ latitude ? latitude : '获取中...' }}</text>
			</view>
			<view class="address-item flex">
				<text class="address-label">出发地：</text>
				<text class="value clickable" @tap="chooseStartLocation">{{ startAddress || '点击选择' }}</text>
			</view>
			<view class="address-item flex">
				<text class="address-label">目的地：</text>
				<text class="value clickable" @tap="chooseDestination">{{ destinationAddress || '点击选择' }}</text>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				latitude: null,
				longitude: null,
				markers: [],
				locationWatcher: null,
				startAddress: '', // 出发地地址
				startLocation: null, // 出发地经纬度
				destinationAddress: '', // 目的地地址
				destinationLocation: null, // 目的地经纬度
				polyline: [], // 路线
				cardPosition: {
					x: 0,
					y: 0
				},
				startPosition: {
					x: 0,
					y: 0
				},
				isDragging: false,
				screenInfo: null,
				cardSize: {
					width: 0,
					height: 0,
					initialTop: 600 // 保存初始top值（300rpx）
				}
			};
		},
		onLoad() {
			this.checkAndGetLocation();
		},
		onShow() {
			// 页面显示时开启实时定位
			if (this.latitude && this.longitude) {
				this.startLocationWatch();
			}
		},
		onHide() {
			// 页面隐藏时不停止定位监听，保持后台定位
		},
		onUnload() {
			// 页面卸载时清理定位监听
			this.stopLocationWatch();
		},
		onReady() {
			// 获取系统信息
			this.screenInfo = uni.getSystemInfoSync();
			console.log('windowHeight', this.screenInfo.windowHeight);
			console.log('windowWidth', this.screenInfo.windowWidth);
			// 获取卡片尺寸
			const query = uni.createSelectorQuery().in(this);
			query.select('.info-card').boundingClientRect(data => {
				if (data) {
					this.cardSize = {
						width: data.width,
						height: data.height,
						initialTop: this.cardSize.initialTop
					};
					console.log('cardSize', this.cardSize);
				}
			}).exec();
		},
		methods: {
			checkAndGetLocation() {
				uni.getSetting({
					success: (res) => {
						if (res.authSetting && res.authSetting["scope.userLocation"]) {
							this.getLocation();
						} else {
							this.requestLocationAuth();
						}
					},
				});
			},
			requestLocationAuth() {
				uni.authorize({
					scope: "scope.userLocation",
					success: () => {
						this.getLocation();
					},
					fail: () => {
						uni.showModal({
							title: "提示",
							content: "需要获取您的地理位置，请授权",
							showCancel: false,
							success: () => {
								uni.openSetting({
									success: (settingRes) => {
										if (settingRes.authSetting[
												"scope.userLocation"]) {
											this.getLocation();
										}
									}
								});
							},
						});
					},
				});
			},
			getLocation() {
				wx.getLocation({
					type: "gcj02",
					isHighAccuracy: true,
					success: (res) => {
						console.log('获取位置成功:', res);
						// 保存初始位置
						this.latitude = res.latitude;
						this.longitude = res.longitude;
						// 设置默认出发地
						this.startLocation = {
							latitude: res.latitude,
							longitude: res.longitude
						};
						// 获取初始位置的地址
						this.getAddressByLocation(res.latitude, res.longitude, true);
					},
					fail: (error) => {
						console.error('获取位置失败:', error);
						this.checkAndGetLocation();
					},
				});
			},
			startLocationWatch() {
				if (this.locationWatcher) {
					return;
				}
				console.log('开始监听位置变化');
				// 直接使用前台定位
				this.startForegroundLocation();
			},
			startForegroundLocation() {
				const locationConfig = {
					type: 'gcj02',
					isHighAccuracy: true,
					success: () => {
						console.log('开启前台定位成功');
						this.setupLocationChange();
					},
					fail: (error) => {
						console.error('开启前台定位失败:', error);
						uni.showToast({
							title: '定位功能异常',
							icon: 'none'
						});
					}
				};

				console.log('正在启动位置更新...');
				wx.startLocationUpdate(locationConfig);
			},
			setupLocationChange() {
				console.log('开始设置位置变化监听');

				// 先清除可能存在的旧监听器
				try {
					wx.offLocationChange();
					console.log('已清除旧的位置监听器');
				} catch (e) {
					console.log('清除旧监听器时出错:', e);
				}

				// 监听位置变化事件
				wx.onLocationChange((res) => {
					// 检查位置是否真的变化
					if (this.hasLocationChanged(res)) {
						this.updateLocation(res);
					}
				});
			},
			hasLocationChanged(newLocation) {
				if (!this.latitude || !this.longitude) {
					console.log('首次定位，直接更新位置');
					return true;
				}

				// 计算位置变化距离（使用简单的经纬度差值计算）
				const latDiff = Math.abs(this.latitude - newLocation.latitude);
				const lngDiff = Math.abs(this.longitude - newLocation.longitude);

				// 设置更大的阈值，减少更新频率
				const threshold = 0.00005; // 大约5米的经纬度变化
				const hasChanged = latDiff > threshold || lngDiff > threshold;

				if (hasChanged) {
					console.log('检测到有效的位置变化:', {
						latDiff: latDiff.toFixed(6),
						lngDiff: lngDiff.toFixed(6),
						threshold: threshold
					});
				}

				return hasChanged;
			},
			updateLocation(res) {
				// 确保数据有效
				if (!res.latitude || !res.longitude) {
					console.log('收到无效的位置数据:', res);
					return;
				}

				this.latitude = res.latitude;
				this.longitude = res.longitude;

				// 更新起点标记
				this.updateMarkers();

				// 获取详细地址
				if (!this.startAddress) {
					wx.getLocation({
						type: 'gcj02',
						isHighAccuracy: true,
						geocode: true,
						success: (result) => {
							console.log('获取地址信息:', result);
							if (result.address) {
								this.startAddress = result.address;
							} else {
								// 如果没有直接返回地址，尝试使用位置选择器
								this.getAddressByLocation();
							}
						},
						fail: (error) => {
							console.error('获取地址失败:', error);
							this.getAddressByLocation();
						}
					});
				}

				// 如果有目的地，更新路线
				if (this.destinationLocation) {
					this.updatePolyline();
				}
			},
			stopLocationWatch() {
				console.log('正在停止位置监听');
				try {
					wx.offLocationChange();
					wx.stopLocationUpdate();
					this.locationWatcher = null;
					console.log('位置监听已停止');
				} catch (e) {
					console.error('停止位置监听时出错:', e);
				}
			},
			// 更新地图标记点
			updateMarkers() {
				this.markers = [];

				// 添加出发地标记
				if (this.startLocation) {
					this.markers.push({
						id: 1,
						latitude: this.startLocation.latitude,
						longitude: this.startLocation.longitude,
						title: "出发地",
						// iconPath: "/static/index/start.png",
						width: 30,
						height: 30
					});
				}

				// 添加目的地标记
				if (this.destinationLocation) {
					this.markers.push({
						id: 2,
						latitude: this.destinationLocation.latitude,
						longitude: this.destinationLocation.longitude,
						title: "目的地",
						// iconPath: "/static/index/end.png",
						width: 30,
						height: 30
					});
				}
			},
			// 根据经纬度获取地址
			getAddressByLocation(latitude, longitude, isInitial = false) {
				if (isInitial) {
					// 如果是初始位置，直接设置经纬度作为出发地
					this.startLocation = {
						latitude: latitude,
						longitude: longitude
					};
					// 尝试获取地址
					uni.getLocation({
						type: 'gcj02',
						geocode: true,
						success: (res) => {
							this.startAddress = res.address ||
							`${latitude.toFixed(6)},${longitude.toFixed(6)}`;
							this.updateMarkers();
						},
						fail: (error) => {
							console.error('获取地址失败:', error);
							this.startAddress = `${latitude.toFixed(6)},${longitude.toFixed(6)}`;
							this.updateMarkers();
						}
					});
				}
			},
			// 选择出发地
			chooseStartLocation() {
				uni.chooseLocation({
					success: (res) => {
						console.log('选择的出发地:', res);
						this.startAddress = res.name || res.address;
						this.startLocation = {
							latitude: res.latitude,
							longitude: res.longitude
						};
						// 更新地图中心点
						this.latitude = res.latitude;
						this.longitude = res.longitude;
						// 更新标记和路线
						this.updateMarkers();
						this.updatePolyline();
					},
					fail: (error) => {
						console.error('选择位置失败:', error);
						uni.showToast({
							title: '选择位置失败',
							icon: 'none'
						});
					}
				});
			},
			// 选择目的地
			chooseDestination() {
				uni.chooseLocation({
					success: (res) => {
						console.log('选择的目的地:', res);
						this.destinationAddress = res.name || res.address;
						this.destinationLocation = {
							latitude: res.latitude,
							longitude: res.longitude
						};
						// 更新标记和路线
						this.updateMarkers();
						this.updatePolyline();
					},
					fail: (error) => {
						console.error('选择位置失败:', error);
						uni.showToast({
							title: '选择位置失败',
							icon: 'none'
						});
					}
				});
			},
			// 更新路线
			updatePolyline() {
				if (!this.startLocation || !this.destinationLocation) return;

				this.polyline = [{
					points: [{
							latitude: this.startLocation.latitude,
							longitude: this.startLocation.longitude
						},
						{
							latitude: this.destinationLocation.latitude,
							longitude: this.destinationLocation.longitude
						}
					],
					color: '#2d8cf0',
					width: 4,
					arrowLine: true,
					borderColor: '#2d8cf0',
					borderWidth: 1
				}];

				// 调整地图视野以包含起点和终点
				const mapContext = uni.createMapContext('trajectoryMap');
				if (mapContext) {
					mapContext.includePoints({
						points: [{
								latitude: this.startLocation.latitude,
								longitude: this.startLocation.longitude
							},
							{
								latitude: this.destinationLocation.latitude,
								longitude: this.destinationLocation.longitude
							}
						],
						padding: [50, 50, 50, 50]
					});
				}
			},
			touchStart(e) {
				const touch = e.touches[0];
				this.startPosition = {
					x: touch.clientX - this.cardPosition.x,
					y: touch.clientY - this.cardPosition.y
				};
				this.isDragging = true;

				// 如果还没有获取到卡片尺寸，重新获取
				if (!this.cardSize.width || !this.cardSize.height) {
					const query = uni.createSelectorQuery().in(this);
					query.select('.info-card').boundingClientRect(data => {
						if (data) {
							this.cardSize = {
								width: data.width,
								height: data.height,
								initialTop: this.cardSize.initialTop
							};
						}
					}).exec();
				}
			},
			touchMove(e) {
				if (!this.isDragging || !this.screenInfo || !this.cardSize.width) return;

				const touch = e.touches[0];
				const screenWidth = this.screenInfo.windowWidth;
				const screenHeight = this.screenInfo.windowHeight;

				// 计算新位置
				let newX = touch.clientX - this.startPosition.x;
				let newY = touch.clientY - this.startPosition.y;

				// 限制X轴范围：不能超出屏幕左右边界
				const maxX = screenWidth - this.cardSize.width;
				newX = Math.max(0, Math.min(maxX, newX));

				// 限制Y轴范围：考虑初始top值
				const initialTop = uni.upx2px(this.cardSize.initialTop); // 将rpx转换为px
				const maxY = screenHeight - this.cardSize.height - initialTop;
				newY = Math.max(-initialTop, Math.min(maxY, newY));

				this.cardPosition = {
					x: newX,
					y: newY
				};
			},
			touchEnd() {
				this.isDragging = false;
			}
		},
	};
</script>

<style lang="scss" scoped>
	.trajectory-container {
		position: relative;
		width: 100%;
		height: 100vh;

		.map-area {
			width: 100%;
			height: 100%;
			position: absolute;
			top: 0;
			left: 0;
			z-index: 1;
		}

		.info-card {
			position: absolute;
			left: 0;
			top: 600rpx;
			width: calc(100% - 60rpx);
			background: rgba(255, 255, 255, 0.95);
			border-radius: 16rpx;
			box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
			padding: 24rpx 20rpx;
			z-index: 2;
			backdrop-filter: blur(10px);
			touch-action: none;
			user-select: none;

			.drag-handle {
				width: 100%;
				height: 20rpx;
				display: flex;
				justify-content: center;
				align-items: center;
				margin-bottom: 10rpx;

				.handle-line {
					width: 60rpx;
					height: 6rpx;
					background: #ddd;
					border-radius: 3rpx;
				}
			}

			.label {
				font-size: 32rpx;
				font-weight: bold;
				color: #2d8cf0;
				margin-bottom: 20rpx;
				display: block;
				text-align: center;
			}

			.coords {
				display: flex;
				align-items: center;
				margin-bottom: 10rpx;
			}

			.address-item {
				width: 100%;
				margin-top: 10rpx;

				align-items: center;

				.value {
					color: #333;
					font-weight: 500;
					margin-left: 8rpx;
					white-space: nowrap;
					overflow: hidden;
					text-overflow: ellipsis;
				}

				.clickable {
					color: #2d8cf0;
					text-decoration: underline;
				}
			}
		}
	}
</style>
